import re
import copy

class Solution:
    def splitsubexpression(self,exp):
        result=[]
        bstack=[]
        index=0
        for i in range(len(exp)):
            if exp[i]=="(":
                if len(bstack)==0:
                    index=i
                bstack.append(0)
            if exp[i]==")":
                bstack.pop()
                if len(bstack)==0:
                    result.append(exp[index:i+1])
        return result
    def evaluate(self, expression: str) -> int:
        pattern=re.compile(r'[(](.*)[)]', re.S)
        backpattern=re.compile(r'[(](.*?)[)]', re.S)
        def calc(expression,map):
            expression=expression[1:-1]
            atoms=expression.split(" ")
            print(expression)
            subexpress=self.splitsubexpression(expression)
            submap=copy.deepcopy(map)
            if atoms[0]=="let":
                for i in range(1,len(atoms),2):
                    if atoms[i][0]!="(" and i+1<len(atoms):
                        try:
                            if re.compile("[a-z]").search(atoms[i+1]):
                                submap[atoms[i]]=submap[atoms[i+1]]
                            else:
                                submap[atoms[i]]=int(atoms[i+1])
                        except:
                            pass
                    else:
                        break
                for exp in subexpress:
                    expression=expression.replace(exp,calc(exp,submap),1)
                    afteratoms=expression.split(" ")
                    for i in range(1,len(afteratoms),2):
                        if afteratoms[i][0]!="(" and i+1<len(afteratoms):
                            try:
                                submap[afteratoms[i]]=int(afteratoms[i+1])
                            except:
                                pass
                        else:
                            break
                    #print(map)
                afteratoms=expression.split(" ")
                for i in range(1,len(afteratoms),2):
                    if afteratoms[i][0]!="(" and i+1<len(afteratoms):
                        try:
                            submap[afteratoms[i]]=int(afteratoms[i+1])
                        except:
                            pass
                    else:
                        break
                if re.compile("[a-z]").search(afteratoms[-1]):
                    # if afteratoms[-1] in map.keys():
                    #     result=map[afteratoms[-1]]
                    # else:
                    result=submap[afteratoms[-1]]
                else:
                    result=int(afteratoms[-1])
                #print(result)
                return str(result)
            elif atoms[0]=="add":
                for exp in subexpress:
                    expression=expression.replace(exp,calc(exp,submap),1)
                afteratoms=expression.split(" ")
                result=0
                if re.compile("[a-z]").search(afteratoms[1]):
                    result=map[afteratoms[1]]
                else:
                    result=int(afteratoms[1])
                if re.compile("[a-z]").search(afteratoms[2]):
                    result+=map[afteratoms[2]]
                else:
                    result+=int(afteratoms[2])
                #print(result)
                return str(result)
            elif atoms[0]=="mult":
                for exp in subexpress:
                    expression=expression.replace(exp,calc(exp,submap),1)       
                afteratoms=expression.split(" ")
                result=0
                if re.compile("[a-z]").search(afteratoms[1]):
                    result=map[afteratoms[1]]
                else:
                    result=int(afteratoms[1])
                if re.compile("[a-z]").search(afteratoms[2]):
                    result*=map[afteratoms[2]]
                else:
                    result*=int(afteratoms[2])
                #print(result)
                return str(result)
        return int(calc(expression,{}))

s=Solution()
print(s.evaluate("(let x 1 y 2 x (add x y) (add x y))"))